package com.xdl.modules.system.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xdl.common.constants.CommonConstants;
import com.xdl.common.exception.BelugaException;
import com.xdl.common.response.ResponseCollection;
import com.xdl.common.response.ResponseResult;
import com.xdl.common.utils.StringUtils;
import com.xdl.configuration.BaseContextHandler;
import com.google.common.collect.Lists;
import com.xdl.modules.system.entity.*;
import com.xdl.modules.system.model.*;
import com.xdl.modules.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author iron guo
 * @since 2022-03-05
 */
@Slf4j
@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserRoleService userRoleService;

    @Autowired
    private SysUserDepartService sysUserDepartService;

    @Autowired
    private SysDepartService sysDepartService;

    @Autowired
    private SysDepartRoleService departRoleService;

    @Autowired
    private SysDepartRoleUserService departRoleUserService;

    @PostMapping("/list")
    public ResponseResult<IPage<SysUser>> queryPageList(@RequestBody SysUserModel model) {
        IPage<SysUser> page = userService.queryPageList(model);
        return ResponseResult.Success(page);
    }

    @PostMapping("/add")
    public ResponseResult<Boolean> add(@RequestBody SysUserDto user) {
        Boolean save = userService.addUser(user);
        return ResponseResult.Success(save);
    }

    @PostMapping("/userRoleList")
    public ResponseResult<IPage<SysUser>> userRoleList(@RequestBody RoleModel model) {
        Page<SysUser> page = new Page<SysUser>(model.getPageNo(), model.getPageSize());
        IPage<SysUser> pageList = userService.getUserByRoleId(page, model);
        return ResponseResult.Success(pageList);
    }

    @PostMapping("/edit")
    public ResponseResult<Boolean> edit(@RequestBody SysUserDto user) {
        SysUser sysUser = userService.getById(user.getId());
        BeanUtils.copyProperties(user, sysUser);
        sysUser.setUpdateTime(LocalDateTime.now());
        sysUser.setPassword(sysUser.getPassword());
        String roles = user.getSelectedroles();
        String departs = user.getSelecteddeparts();
        if (StringUtils.isEmpty(departs)) {
            //vue3.0前端只传递了departIds
            departs = user.getDepartIds();
        }
        // 修改用户走一个service 保证事务
        Boolean edit = userService.editUser(sysUser, roles, departs);
        return ResponseResult.Success(edit);
    }

    /**
     * 给指定角色添加用户
     *
     * @param
     * @return
     */
    @PostMapping("/addSysUserRole")
    public ResponseResult<String> addSysUserRole(@RequestBody SysUserRoleModel sysUserRoleVO) {
        String sysRoleId = sysUserRoleVO.getRoleId();
        for (String sysUserId : sysUserRoleVO.getUserIdList()) {
            SysUserRole sysUserRole = new SysUserRole().setRoleId(sysRoleId).setUserId(sysUserId);
            QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<SysUserRole>();
            queryWrapper.lambda().eq(SysUserRole::getRoleId, sysRoleId).eq(SysUserRole::getUserId, sysUserId);
            SysUserRole one = userRoleService.getOne(queryWrapper);
            if (one == null) {
                userRoleService.save(sysUserRole);
            }
        }
        return ResponseResult.Success();
    }


    /**
     * 批量删除指定角色的用户关系
     *
     * @param
     * @return
     */
    @DeleteMapping("/deleteUserRoleBatch")
    public ResponseResult<SysUserRole> deleteUserRoleBatch(
            @RequestParam(name = "roleId") String roleId,
            @RequestParam(name = "userIds", required = true) String userIds) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<SysUserRole>();
        queryWrapper.eq("role_id", roleId).in("user_id", Arrays.asList(userIds.split(",")));
        userRoleService.remove(queryWrapper);
        return ResponseResult.Success();
    }

    /**
     * 删除指定角色的用户关系
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/deleteUserRole", method = RequestMethod.DELETE)
    public ResponseResult<Boolean> deleteUserRole(@RequestParam(name = "roleId") String roleId,
                                                  @RequestParam(name = "userId", required = true) String userId
    ) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<SysUserRole>();
        queryWrapper.eq("role_id", roleId).eq("user_id", userId);
        boolean remove = userRoleService.remove(queryWrapper);
        return ResponseResult.Success(remove);
    }


    /**
     * 修改密码
     */
    @PostMapping("/changePassword")
    public ResponseResult<Boolean> changePassword(@RequestBody SysUser sysUser) {
        SysUser u = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
        if (u == null) {
            return ResponseResult.Error("用户不存在！");
        }
        u.setPassword(sysUser.getPassword());
        Boolean change = userService.changePassword(u);
        return ResponseResult.Success(change);
    }


    @GetMapping("/queryUserRole")
    public ResponseCollection<String> queryUserRole(@RequestParam(name = "userid", required = true) String userid) {
        List<String> list = Lists.newArrayList();
        List<SysUserRole> userRole = userRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, userid));
        if (userRole == null || userRole.size() <= 0) {
            BelugaException.fatal("未找到用户相关角色信息");
        } else {
            for (SysUserRole sysUserRole : userRole) {
                list.add(sysUserRole.getRoleId());
            }
        }
        return ResponseCollection.Success(list);
    }


    /**
     * 查询指定用户和部门关联的数据
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/userDepartList", method = RequestMethod.GET)
    public ResponseCollection<DepartIdModel> getUserDepartsList(@RequestParam(name = "userId", required = true) String userId) {
        List<DepartIdModel> depIdModelList = this.sysUserDepartService.queryDepartIdsOfUser(userId);
        if (depIdModelList != null && depIdModelList.size() > 0) {
            return ResponseCollection.Success(depIdModelList);
        } else {
            return ResponseCollection.Error("查询失败！");
        }
    }

    /**
     * 冻结&解冻用户
     *
     * @param jsonObject
     * @return
     */
    @PostMapping("frozenBatch")
    public ResponseResult<?> frozenBatch(@RequestBody JSONObject jsonObject) {
        String ids = jsonObject.getString("ids");
        String status = jsonObject.getString("status");
        String[] arr = ids.split(",");
        for (String id : arr) {
            if (StringUtils.isNotEmpty(id)) {
                SysUser user = userService.getById(id);
                user.setStatus(Integer.parseInt(status));
                user.setUpdateTime(LocalDateTime.now());
                user.setUpdateBy(BaseContextHandler.getUsername());
                userService.updateById(user);
            }
        }
        return ResponseResult.Success("操作成功!");

    }

    @DeleteMapping("/delete")
    public ResponseResult<?> delete(@RequestParam(name = "id", required = true) String id) {
        this.userService.removeById(id);
        return ResponseResult.Success("删除用户成功");
    }

    /**
     * 获取被逻辑删除的用户列表，无分页
     *
     * @return logicDeletedUserList
     */
    @GetMapping("/recycleBin")
    public ResponseCollection<SysUser> getRecycleBin() {
        List<SysUser> logicDeletedUserList = userService.deletelist();
        if (logicDeletedUserList.size() > 0) {
            // 批量查询用户的所属部门
            // step.1 先拿到全部的 userIds
            List<String> userIds = logicDeletedUserList.stream().map(SysUser::getId).collect(Collectors.toList());
            // step.2 通过 userIds，一次性查询用户的所属部门名字
            Map<String, String> useDepNames = userService.getDepNamesByUserIds(userIds);
            logicDeletedUserList.forEach(item -> item.setOrgCode(useDepNames.get(item.getId())));
        }
        return ResponseCollection.Success(logicDeletedUserList);
    }

    /**
     * 还原被逻辑删除的用户
     *
     * @param userIds
     * @return
     */
    @GetMapping("/putRecycleBin")
    public ResponseResult<String> putRecycleBin(@RequestParam String userIds) {
        if (StringUtils.isNotBlank(userIds)) {
            SysUser updateUser = new SysUser();
            updateUser.setUpdateBy(BaseContextHandler.getUsername());
            updateUser.setUpdateTime(LocalDateTime.now());
            Boolean flag = userService.revertLogicDeleted(Arrays.asList(userIds.split(",")), updateUser);
        }
        return ResponseResult.Success("还原成功！");
    }

    /**
     * 彻底删除用户
     *
     * @param userIds 被删除的用户ID，多个id用半角逗号分割
     * @return
     */
    @DeleteMapping("/deleteRecycleBin")
    public ResponseResult<Boolean> deleteRecycleBin(@RequestParam("userIds") String userIds) {
        if (StringUtils.isNotBlank(userIds)) {
            Boolean flag = userService.deleteRecycleBin(Arrays.asList(userIds.split(",")));
        }
        return ResponseResult.Success("删除成功");
    }


    /**
     * 部门用户列表
     */
    @RequestMapping(value = "/departUserList", method = RequestMethod.POST)
    public ResponseResult<IPage<SysUser>> departUserList(@RequestBody DepartUserModel model) {
        Page<SysUser> page = new Page<SysUser>(model.getPageNo(), model.getPageSize());
        //根据部门ID查询,当前和下级所有的部门IDS
        List<String> subDepids = Lists.newArrayList();
        //部门id为空时，查询我的部门下所有用户
        if (StringUtils.isEmpty(model.getDepId())) {
            String userid = BaseContextHandler.getUserID();
            Assert.notNull(userid, "账号登陆异常！");
            SysUser sysUser = userService.getById(userid);
            int userIdentity = sysUser.getUserIdentity() != null ? sysUser.getUserIdentity() : CommonConstants.USER_IDENTITY_1;
            if (StringUtils.isNotEmpty(userIdentity) && userIdentity == CommonConstants.USER_IDENTITY_2) {
                subDepids = sysDepartService.getMySubDepIdsByDepId(sysUser.getDepartIds());
            }
        } else {
            subDepids = sysDepartService.getSubDepIdsByDepId(model.getDepId());
        }
        if (subDepids != null && subDepids.size() > 0) {
            IPage<SysUser> pageList = userService.getUserByDepIds(page, subDepids, model.getUsername());
            //批量查询用户的所属部门
            //step.1 先拿到全部的 useids
            //step.2 通过 useids，一次性查询用户的所属部门名字
            List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
            if (userIds != null && userIds.size() > 0) {
                Map<String, String> useDepNames = userService.getDepNamesByUserIds(userIds);
                pageList.getRecords().forEach(item -> {
                    //批量查询用户的所属部门
                    item.setOrgCode(useDepNames.get(item.getId()));
                });
            }
            return ResponseResult.Success(pageList);
        }
        return ResponseResult.Success();
    }


    /**
     * 给指定部门添加对应的用户
     */
    @PostMapping("/editSysDepartWithUser")
    public ResponseResult<String> editSysDepartWithUser(@RequestBody SysDepartUsersModel sysDepartUsersModel) {
        String sysDepId = sysDepartUsersModel.getDepId();
        for (String sysUserId : sysDepartUsersModel.getUserIdList()) {
            SysUserDepart sysUserDepart = new SysUserDepart().setUserId(sysUserId).setDepId(sysDepId);
            QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<SysUserDepart>();
            queryWrapper.eq("dep_id", sysDepId).eq("user_id", sysUserId);
            SysUserDepart one = sysUserDepartService.getOne(queryWrapper);
            if (one == null) {
                sysUserDepartService.save(sysUserDepart);
            }
        }
        return ResponseResult.Success();
    }


    /**
     * 根据 orgCode 查询用户，包括子部门下的用户
     * 针对通讯录模块做的接口，将多个部门的用户合并成一条记录，并转成对前端友好的格式
     */
    @PostMapping("/queryByOrgCodeForAddressList")
    public ResponseResult<?> queryByOrgCodeForAddressList(@RequestBody AddressListModel model) {
        IPage<SysUserSysDepartModel> pageList = userService.queryUserByOrgCode(model);
        List<SysUserSysDepartModel> list = pageList.getRecords();
        // 记录所有出现过的 user, key = userId
        Map<String, JSONObject> hasUser = new HashMap<>(list.size());
        JSONArray resultJson = new JSONArray(list.size());
        for (SysUserSysDepartModel item : list) {
            String userId = item.getId();
            // userId
            JSONObject getModel = hasUser.get(userId);
            // 之前已存在过该用户，直接合并数据
            if (getModel != null) {
                String departName = getModel.get("departName").toString();
                getModel.put("departName", (departName + " | " + item.getDepartName()));
            } else {
                // 将用户对象转换为json格式，并将部门信息合并到 json 中
                JSONObject json = JSON.parseObject(JSON.toJSONString(item));
                json.remove("id");
                json.put("userId", userId);
                json.put("departId", item.getDepartId());
                json.put("departName", item.getDepartName());
//              json.put("avatar", item.getSysUser().getAvatar());
                resultJson.add(json);
                hasUser.put(userId, json);
            }
        }
        IPage<JSONObject> result = new Page<>(model.getPageNo(), model.getPageSize(), pageList.getTotal());
        result.setRecords(resultJson.toJavaList(JSONObject.class));
        return ResponseResult.Success(result);
    }


    /**
     * 删除指定机构的用户关系
     */
    @DeleteMapping("/deleteUserInDepart")
    public ResponseResult<SysUserDepart> deleteUserInDepart(
            @RequestParam(name = "depId") String depId,
            @RequestParam(name = "userId", required = true) String userId) {
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<SysUserDepart>();
        queryWrapper.lambda().eq(SysUserDepart::getDepId, depId).eq(SysUserDepart::getUserId, userId);
        boolean b = sysUserDepartService.remove(queryWrapper);
        if (b) {
            List<SysDepartRole> sysDepartRoleList = departRoleService.list(new QueryWrapper<SysDepartRole>().lambda().eq(SysDepartRole::getDepartId, depId));
            List<String> roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
            if (roleIds != null && roleIds.size() > 0) {
                QueryWrapper<SysDepartRoleUser> query = new QueryWrapper<>();
                query.lambda().eq(SysDepartRoleUser::getUserId, userId).in(SysDepartRoleUser::getDroleId, roleIds);
                departRoleUserService.remove(query);
            }
            return ResponseResult.Success("删除成功!");
        } else {
            return ResponseResult.Success("当前选中部门与用户无关联关系!");
        }
    }

    /**
     * 批量删除指定机构的用户关系
     */
    @RequestMapping(value = "/deleteUserInDepartBatch", method = RequestMethod.DELETE)
    public ResponseResult<SysUserDepart> deleteUserInDepartBatch(
            @RequestParam(name = "depId") String depId,
            @RequestParam(name = "userIds", required = true) String userIds) {
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<SysUserDepart>();
        queryWrapper.lambda().eq(SysUserDepart::getDepId, depId).in(SysUserDepart::getUserId, Arrays.asList(userIds.split(",")));
        boolean b = sysUserDepartService.remove(queryWrapper);
        if (b) {
            departRoleUserService.removeDeptRoleUser(Arrays.asList(userIds.split(",")), depId);
        }
        return ResponseResult.Success();
    }

    /**
     * 查询当前用户的所有部门/当前部门编码
     *
     * @return
     */
    @RequestMapping(value = "/getCurrentUserDeparts", method = RequestMethod.GET)
    public ResponseResult<Map<String, Object>> getCurrentUserDeparts() {
        String userid = BaseContextHandler.getUserID();
        Assert.notNull(userid, "账号登陆异常！");
        SysUser sysUser = userService.getById(userid);
        List<SysDepart> list = this.sysDepartService.queryUserDeparts(sysUser.getId());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("list", list);
        map.put("orgCode", sysUser.getOrgCode());
        return ResponseResult.Success(map);
    }

    /**
     * 登陆成功选择用户当前部门
     * @param user
     * @return
     */
    @RequestMapping(value = "/selectDepart", method = RequestMethod.PUT)
    public ResponseResult<JSONObject> selectDepart(@RequestBody SysUser user) {
        String username = user.getUsername();
        if(StringUtils.isEmpty(username)) {
            String userid = BaseContextHandler.getUserID();
            Assert.notNull(userid, "账号登陆异常！");
            SysUser sysUser = userService.getById(userid);
            username = sysUser.getUsername();
        }
        String orgCode= user.getOrgCode();
        this.userService.updateUserDepart(username, orgCode);
        SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername,username));
        JSONObject obj = new JSONObject();
        obj.put("userInfo", sysUser);
        return ResponseResult.Success(obj);
    }

}
